package com.gujiangbo.defrewlock;

public class WriteLock implements Lock {

    private final ReadWriteLockImpl readWriteLock;


    public WriteLock(ReadWriteLockImpl readWriteLock) {
        this.readWriteLock = readWriteLock;
    }

    @Override
    public void lock() throws InterruptedException {

        synchronized (readWriteLock.getMutex()) {
            try {
                //首先使等待获取写入锁的数字加一
                readWriteLock.incrementWaitingWriters();
                //如果此时有其它线程正在进行读操作，或者写操作，那么当前线程挂起
                while (readWriteLock.getReadingReaders() > 0 ||
                        readWriteLock.getWritingWriters() > 0) {
                    readWriteLock.getMutex().wait();
                }
            } finally {
                //成功获取到写入锁,使得等待区的写入锁的计数器减一
                this.readWriteLock.decrementWaitingWriters();
            }
            // 将正在写入的锁的数量加一
            readWriteLock.incrementWritingWriters();
        }

    }

    @Override
    public void unlock() {
        synchronized (readWriteLock.getMutex()) {
            //减少正在写入锁的数量计数器
            readWriteLock.decrementWritingWriters();
            //设置偏好，可以使得读锁被最快速的获取
            readWriteLock.changePerfer(false);
            //通知唤醒其他mutex monitor waitset中的线程
            readWriteLock.getMutex().notifyAll();
        }

    }
}
